import type { CollapsiblePanel } from '../../components/collapsible_panel'
import type { ColorPicker } from '../../components/color_picker'
import type { TextEditor } from '../../components/combined/text_editor'
import type { UploadInput } from '../../components/combined/upload_input'
import type { RangeSlider } from '../../components/range_slider'
import type { Select } from '../../components/select'
import type { ShortcutInput } from '../../components/shortcuts'
import type { StyleEditor } from '../../components/style_editor'
import type { TextInput } from '../../components/text_input'
import type { ComponentStyleIdType } from './style_id'

/**
 * 组件接口
 */
export interface IComponent {
  name: ComponentStyleIdType
  description: string
  props?: any
  styleId: string
  render: () => void
  bindEvents: (element: JQuery<HTMLElement>) => void
  createStyleTag: () => void
}

/**
 * 组件基类
 */
export abstract class BaseComponent implements IComponent {
  /**
   * 组件名称
   */
  abstract name: ComponentStyleIdType
  /**
   * 组件描述
   */
  abstract description: string
  /**
   * 组件属性
   */
  abstract props?: any
  /**
   * 组件样式 ID
   */
  abstract styleId: string
  /**
   * 组件元素
   */
  $element: JQuery<HTMLElement> | undefined = undefined
  /**
   * 生成组件 HTML 字符串
   */
  abstract render(): void
  /**
   * 挂载组件
   */
  mount(element: JQuery<HTMLElement>): void {
    this.$element = element
    this.bindEvents(element)
  }

  /**
   * 绑定事件
   */
  abstract bindEvents(element: JQuery<HTMLElement>): void
  /**
   * 创建样式标签
   */
  abstract createStyleTag(): void
  /**
   * 重置组件
   */
  abstract reset(): void
  /**
   * 销毁组件
   */
  destroy(): void {}
}

/**
 * 文件来源
 */
export const FILE_UPLOAD_MODE: Record<string, FileUploadMode> = {
  URL: 'url',
  FILE: 'file',
}

/**
 * 资源来源
 */
export const RESOURCE_ORIGIN: Record<string, ResourceOrigin> = {
  URL: 'url',
  LOCAL: 'local',
}

/**
 * 组件类型
 */
export type ComponentType = Select | RangeSlider | ColorPicker | UploadInput | TextEditor | StyleEditor | CollapsiblePanel | TextInput | ShortcutInput
